package com.base.myproject.client.ui;

import java.util.ArrayList;
import java.util.HashMap;

import com.base.myproject.client.busi.BaseStore;
import com.base.myproject.client.busi.BaseStoreEvent;
import com.base.myproject.client.busi.BaseStoreListener;
import com.base.myproject.client.busi.Editdisable;
import com.base.myproject.client.busi.BO.BaseObject;
import com.base.myproject.client.busi.BO.BusiObject;
import com.base.myproject.client.tools.Debug;
import com.extjs.gxt.ui.client.Style.SelectionMode;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.MenuEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.util.KeyNav;
import com.extjs.gxt.ui.client.widget.grid.AggregationRowConfig;
import com.extjs.gxt.ui.client.widget.grid.CellSelectionModel;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.EditorGrid;
import com.extjs.gxt.ui.client.widget.grid.GridSelectionModel;
import com.extjs.gxt.ui.client.widget.grid.GridView;
import com.extjs.gxt.ui.client.widget.grid.GridViewConfig;
import com.extjs.gxt.ui.client.widget.menu.Item;
import com.extjs.gxt.ui.client.widget.menu.Menu;
import com.extjs.gxt.ui.client.widget.menu.MenuItem;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Event;

public class BaseGrid<M extends ModelData> extends EditorGrid<M> implements
		Listener, LinkParent {
	BaseStore store = null;
	BaseStore linkparent = null;
	private BaseGrid parent = null; // main store
	// private ArrayList<BaseGrid> chileBaseGrid = new ArrayList<BaseGrid>();
	// //chile list
	// String[] linkparentcolumns = null;
	String tablename = null;
	static int count = 0;
	private BaseGrid basegrid = null;

	public BaseGrid(BaseStore store, ColumnModel cm) {
		this(store, cm, true, true);
	}
	
	public BaseGrid(BaseStore store, ColumnModel cm, boolean onlyAdd) {
		this(store, cm, true, true, onlyAdd);
	}

	public BaseGrid(BaseStore store, ColumnModel cm, boolean contentmenu,
			boolean contentkeynav) {
		this(store, cm, contentmenu, contentkeynav, false);
	}
	
	public BaseGrid(BaseStore store, ColumnModel cm, boolean contentmenu,
			boolean contentkeynav, GridView view) {
		this(store, cm, contentmenu, contentkeynav, false);
	}

	/**
	 * 
	 * @param store
	 * @param cm
	 * @param contentmenu
	 *            true显示右键和下方的添加删除
	 * @param contentkeynav
	 *            true可以使用快捷键添加删除
	 * @param onlyAdd 
	 * 			  true的话只显示添加按钮，并且只显示保存和添加的弹出菜单
	 */
	//小陈2011-03-08修改，修改了只作添加操作时只显示添加按钮
	public BaseGrid(BaseStore store, ColumnModel cm, boolean contentmenu,
			boolean contentkeynav, boolean onlyAdd) {
		super(store, cm);
		count++;
		basegrid = this;
		ColumnConfig add = new ColumnConfig("add_new_row", "", 1);
		
		add.setMenuDisabled(false);
		add.setResizable(false);
		add.setSortable(false);
		add.setWidth(10);
		add.setStyle("width:1px;");
		cm.getColumns().add(0, add);

		if (contentmenu) {
			if(cm.getColumnCount()>0)
			{
			AggregationRowConfig agg = new AggregationRowConfig();
			GWT.log("id="+cm.getColumn(0).getId());
//			agg.setCellStyle(cm.getColumn(0).getId(), "width:215px");
			javascript(count + "", this);
			String htmlString = "<a title=\"添加\"  href=\"javascript:void(0);\" onclick=\"javascript:grid_function_map["
				+ count
				+ "]()\"> <img  src='images/baseimage/addrecord.png' ></a>";
			if (!onlyAdd) {
				htmlString += "<a title=\"删除\" href=\"javascript:void(0);\" onclick=\"javascript:grid_delete_map["
				+ count
				+ "]()\"> <img  src='images/baseimage/deleterecord.png' ><a title=\"取消删除\" href=\"javascript:void(0);\" onclick=\"javascript:grid_cancel_delete_map["
				+ count
				+ "]()\"> <img  src='images/baseimage/canceldelete.png' ></a>";
			}
			
			agg
					.setHtml(
							cm.getColumn(0).getId(),
							htmlString);
			// agg.setWidget(cm.getColumn(3).getId(), new Button("ssss"));
			cm.addAggregationRow(agg);
			}
			
		}

		setStore(store);
		setClicksToEdit(ClicksToEdit.ONE);
		// this.store = store;
		setSelectionModel(new CellSelectionModel());
		setBorders(true);
		setLoadMask(true);
		if (contentmenu) {
			ContentMenu(onlyAdd);
		}
		
		if (contentkeynav) {
			KeyNav kn = new KeyNav(this) {
				public void onKeyPress(ComponentEvent ce) {

					if (ce.isControlKey() && ce.getKeyCode() == 78) // ctr+n
					{
						// System.out.println(83+"");
						addnewrecord();

					} else if (ce.isControlKey() && ce.getKeyCode() == 68) // ctr+d
					{
						deleterecord();
					}
				}

			};
		}
		
		
		if(store.isNeedtodeelroweditable())
    	{
			GridViewConfig  gbg = new GridViewConfig ()
			{
				public String getRowStyle(ModelData model, int rowIndex, ListStore ds) {
					
					if(RowDisable(rowIndex))
					{
						return "base-x-panel-body-disabled";
					}
					return "";
				  }

			};
    		this.getView().setViewConfig(gbg);
    
		
    	}
		//zgw 2010-10-04
		store.addBaseStoreListener(BaseStoreEvent.EventType.ROW_CHANGED, new BaseStoreListener(){

			@Override
			public void BaseStoreEventHandle(BaseStoreEvent evt) {
			//zgw 2010-10-24 bug : baseliveview ,when de row changed,and the baseliveview is changed to de new page .
				//the row can't be selected.
				//if(evt.getCurrowindex()!=basegrid.getStore().getCurcowindex())
				{
				if(basegrid.getSelectionModel().getSelectionMode().equals(SelectionMode.SINGLE))
					basegrid.getSelectionModel().select(evt.getCurrowindex(), false);
				}
			}

			@Override
			public void onBrowserEvent(Event event) {
				// TODO Auto-generated method stub
				
			}
			
		});
		
		this.addListener(Events.ViewReady, new Listener<BaseEvent>(){

			@Override
			public void handleEvent(BaseEvent be) {
				
				if(basegrid.getStore().getCount()>0)
				basegrid.getSelectionModel().select(0, false);
			}
			
		});
//		 if(view !=null)
//		 this.setView(view);

		// store.addBaseStoreListener(BaseStoreEvent.EventType.LOAD_COMPLETE,
		// new BaseStoreListener() {
		//
		// @Override
		// public void BaseStoreEventHandle(BaseStoreEvent evt) {
		//
		// System.out
		// .println("BaseStoreEventHandle in BaseGrid..."
		// + evt.getEventType());
		// // basegrid.getView().refresh(true);
		// }
		//
		// @Override
		// public void onBrowserEvent(Event event) {
		// // TODO Auto-generated method stub
		//
		// }
		//
		// });

	}
	boolean RowDisable(int rowIndex)
	{
		for(Editdisable edisable :(ArrayList<Editdisable>) ((BaseStore) this.store).getEditdisablelist())
		{
			if(edisable.getEdittype().equals(BaseStore.EditDisableType.EQUALS))
			{
				if(store.getValue(rowIndex, edisable.getColumnname()) !=null && store.getValue(rowIndex, edisable.getColumnname()).equals(edisable.getValue()))
				{
					return true;
				}
			}
			else if(edisable.getEdittype().equals(BaseStore.EditDisableType.IN))
			{
				if(store.getValue(rowIndex, edisable.getColumnname()) !=null &&  store.getValue(rowIndex, edisable.getColumnname()).toString().indexOf(edisable.getValue())>=0)
				{
					return true;
				}
			}
			else if(edisable.getEdittype().equals(BaseStore.EditDisableType.LIKE))
			{
				
			}	
		}
		return false;
	}

	protected void trysave() {
		this.getStore().trySave();
	}

	/**
	 * 删除记录 2010-10-16 改动可以移动到-1行
	 */
	public void deleterecord() {
		int idx = -1;
		if (basegrid.getSelectionModel().getSelectedItems().size() > 0) {
			idx = basegrid.getStore().indexOf(
					basegrid.getSelectionModel().getSelectedItem());

			// System.out.println(basegrid.getStore().getAt(idx).getClass());
			// basegrid.getStore().remove((JDBCModelData)basegrid.getSelectionModel().getSelectedItem());
			basegrid.getStore().remove(basegrid.getStore().getAt(idx));
//			idx = idx <= 0 ? -1 : idx - 1;
			
			idx = idx <= 0 ? 0 : idx - 1;  //小陈修改成0了，不然当grid为最后一行时会报错
		}
	
		basegrid.getStore().gotorow(idx);
		
		
//		basegrid.getSelectionModel().select(idx, false);
		
		
		
		// basegrid.getData()
		// TODO
		// 有bug，不过目前不会显现，basegrid.getSelectionModel().select(0);basegrid并不会立马接受到换行事件
		//
		/*
		 * if(basegrid.getStore().indexOf(basegrid.getSelectionModel().getSelectedItem
		 * ())>=0) {
		 * 
		 * basegrid.getStore().gotorow(basegrid.getStore().indexOf(basegrid.
		 * getSelectionModel().getSelectedItem())); }
		 */

	}

	/**
	 * 添加记录
	 */
	@SuppressWarnings("unchecked")
	public void addnewrecord() {
		stopEditing();
		HashMap hm = new HashMap();

		BusiObject jdbcml = new BusiObject(hm);
		getStore().add(jdbcml);
		//zgw 2010-10-04 屏蔽
		//basegrid.getSelectionModel().select(jdbcml, false);
		
		
		// System.out.println("editor=="+basegrid.getColumnModel().getColumn(0).getEditor().getClass());
		// System.out.println("editor1=="+basegrid.getColumnModel().getColumn(1).getEditor().getClass());
		// System.out.println("editor2=="+basegrid.getColumnModel().getColumn(2).getEditor().getField().getClass());
		// System.out.println("editor3=="+basegrid.getColumnModel().getColumn(3).getEditor().getClass());
		// System.out.println("editor4=="+basegrid.getColumnModel().getColumn(4).getEditor().getClass());
		// System.out.println("editor5=="+basegrid.getColumnModel().getColumn(5).getEditor().getClass());
		//		
		// System.out.println("editor0=="+basegrid.getColumnModel().getColumns());

	}

	/**
	 * 取消删除
	 */
	public void canceldelete() {
		int idx = 0;
		if (basegrid.getSelectionModel().getSelectedItems().size() > 0) {
			idx = basegrid.getStore().indexOf(
					basegrid.getSelectionModel().getSelectedItem());

			// basegrid.getStore().remove(basegrid.getStore().getAt(idx));
			basegrid.getStore().removeStatus(idx, BaseObject.CANCELDELETE);
		}

	}

	public Object getValue(int index, String name) {
		return ((BaseStore) this.getStore()).getValue(index, name);
	}

	// true 是主表，否则是子表
	// public boolean isParent()
	// {
	// return chileBaseGrid.size()>0;
	// }
	//		
	// public void addChileGrid(BaseGrid bg)
	// {
	// chileBaseGrid.add(bg);
	// }
	//		
	public void setSelectionModel(GridSelectionModel<M> sm) {
		super.setSelectionModel(sm);
		//zgw 2009-12-29 增加换行前处理
		sm.addListener(Events.BeforeSelect, this);
		sm.addListener(Events.SelectionChange, this);
		sm.addListener(Events.AfterSelect, this);

	}

	public GridSelectionModel<M> getSelectionModel() {
		return sm;
	}

	public Object getValue(String name) {
		int index = this.getStore().indexOf(
				this.getSelectionModel().getSelectedItem());
		if (index < 0)
			index = 0;
		if (index >= 0)
			return ((BaseStore) this.getStore()).getValue(index, name);

		return null;
	}

	public void setValue(int index, String name, Object value) {
		((BaseStore) this.getStore()).setValue(index, name, value);
		// this.getView().refresh(true);
		this.getView().refreshRow(index);
		// com.extjs.gxt.ui.client.util.Util.
		// Ext.query("");
		// System.out.println("-------");
		// System.out.println("ve===="+this.getView().getBody().childNode(0).childNode(1));
		// Element e = this.getView().getBody().childNode(0).childNode(1).dom;
		// System.out.println(e);
		//		  
		// NodeList<Node> nl =
		// this.getView().getBody().childNode(0).dom.getChildNodes();
		// for(int i=0;i<nl.getLength();i++)
		// {
		// System.out.println("--"+ nl.getItem(i));
		// }
		//	
		// System.out.println("e===="+
		// this.getView().getBody().childNode(0).childNode(0).childNode(0).childNode(0).childNode(0).childNode(1).childNode(0).setInnerHtml("300333"));
		// //
		// System.out.println("ve===="+this.getView().getBody().childNode(0).childNode(0).childNode(1).dom.getAttribute("rowIndex"));
		//		  
		// System.out.println(this.getView().getBody().childNode(0).childNode(0).childNode(0).childNode(0).childNode(0).childNode(1).childNode(0).query("x-grid3-cell-inner x-grid3-col-Sender").length);
	}

	public void setValue(String name, Object value) {
		int index = this.getStore().indexOf(
				this.getSelectionModel().getSelectedItem());
		if (index >= 0)
			setValue(index, name, value);
	}

	public BaseStore getStore() {
		return store;
	}

	public void setStore(BaseStore store) {
		this.store = store;
		this.setTablename(store.getTablename());
	}

	// public BaseGrid getLinkparent() {
	// return parent;
	// }
	// public void setLinkparent(BaseGrid parent) {
	// this.parent =parent;
	// this.parent.addChileGrid(this);
	// }
	

	public String getTablename() {
		return tablename;
	}

	public void setTablename(String tablename) {
		this.tablename = tablename;
	}

	// public String[] getLinkparentcolumns() {
	// return linkparentcolumns;
	// }
	// public void setLinkparentcolumns(String[] linkparentcolumns) {
	// this.linkparentcolumns = linkparentcolumns;
	// }
	@Override
	public void handleEvent(BaseEvent be) {
		

		if (be.getType() == Events.SelectionChange) {
			
			if (store != null) {
				// Debug.printf(((GridSelectionModel)be.getSource()).getSelectedItem().get("cname"));
				int row = store.indexOf(((GridSelectionModel) be.getSource())
						.getSelectedItem());
				// Debug.printf("row="+row);
				if (row >= 0)
					store.gotorow(row);

			}
		
		}
		else if(be.getType() == Events.BeforeSelect)
		{
			
			 be.setCancelled(!canbeChangerow());
			 
			 doBeforeRowChange();
		}
		else if(be.getType() == Events.AfterSelect)
		{
			
			 
			// doBeforeRowChange();
		}

	}
/**
 * 判断是否可以换行，子类重载 true可以，false 阻止换行
 * @return
 */
	public boolean canbeChangerow()
	{
		return true;
	}
	/**
	 * 换行前处理
	 */
	public void doBeforeRowChange()
	{
		
	}
	@Override
	public BaseStore getLinkparent() {
		// TODO Auto-generated method stub
		return linkparent;
	}

	@Override
	public void setLinkparent(BaseStore lp) {
		// TODO Auto-generated method stub
		linkparent = lp;
	}

	Menu m = new Menu();
	/**
	 * @param onlyAdd 是否只显示添加和保存按钮，为false的话会增加一个删除按钮
	 */
	public void ContentMenu(boolean onlyAdd) {
		
		Item item = new MenuItem("添加一行	ctr+n",
				new SelectionListener<MenuEvent>() {

					@Override
					public void componentSelected(MenuEvent ce) {
						addnewrecord();
					}

				});
		Item trysaveitem = new MenuItem("保存		ctr+s",
				new SelectionListener<MenuEvent>() {

					@Override
					public void componentSelected(MenuEvent ce) {
						trysave();
					}

				});
		
		m.add(item);
		
		//如果只是做添加操作的话，就不显示删除行
		if (!onlyAdd) {
			Item deleteitem = new MenuItem("删除行		ctr+d",
					new SelectionListener<MenuEvent>() {

						@Override
						public void componentSelected(MenuEvent ce) {
							deleterecord();
						}

					});
			m.add(deleteitem);
		}
		
		m.add(trysaveitem);
		this.setContextMenu(m);
	}
	
	public Menu getMenu() {
		return m;
	}

	private native void javascript(String str, BaseGrid bgzz)/*-{
		$wnd.grid_function_map[str] = function(){

		bgzz.@com.base.myproject.client.ui.BaseGrid::addnewrecord()();
		//bgzz.@com.base.myproject.client.ui.BaseGrid::aa(Lcom/base/myproject/client/ui/BaseGrid;)(bgzz);

		}


		$wnd.grid_delete_map[str] = function(){

		bgzz.@com.base.myproject.client.ui.BaseGrid::deleterecord()();

		}
		$wnd.grid_cancel_delete_map[str] = function(){

		bgzz.@com.base.myproject.client.ui.BaseGrid::canceldelete()();

		}
	}-*/;
}
